From: Keir Fraser Date: Sat, 13 Oct 2007 07:44:06 +0000 (+0100) Subject: vt-d: disable protected memory registers after vt-d is enabled. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14847^2~47 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=c92739e06d6a68089a656a3ffea9cb26db720f1b;p=xen.git vt-d: disable protected memory registers after vt-d is enabled. Signed-off-by: Allen Kay --- diff --git a/xen/arch/x86/hvm/vmx/vtd/dmar.h b/xen/arch/x86/hvm/vmx/vtd/dmar.h index e6cdf62fab..5c90ad118a 100644 --- a/xen/arch/x86/hvm/vmx/vtd/dmar.h +++ b/xen/arch/x86/hvm/vmx/vtd/dmar.h @@ -87,6 +87,13 @@ struct acpi_ioapic_unit { }ioapic; }; +#define DMAR_OPERATION_TIMEOUT (HZ*60) /* 1m */ +#define time_after(a,b) \ + (typecheck(unsigned long, a) && \ + typecheck(unsigned long, b) && \ + ((long)(b) - (long)(a) < 0)) + int vtd_hw_check(void); +void disable_pmr(struct iommu *iommu); #endif // _DMAR_H_ diff --git a/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c b/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c index 85e3786aac..f8e3b09d68 100644 --- a/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c +++ b/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c @@ -40,13 +40,6 @@ extern void print_iommu_regs(struct acpi_drhd_unit *drhd); extern void print_vtd_entries(struct domain *d, int bus, int devfn, unsigned long gmfn); -#define DMAR_OPERATION_TIMEOUT (HZ*60) /* 1m */ - -#define time_after(a,b) \ - (typecheck(unsigned long, a) && \ - typecheck(unsigned long, b) && \ - ((long)(b) - (long)(a) < 0)) - unsigned int x86_clflush_size; void clflush_cache_range(void *adr, int size) { @@ -1774,7 +1767,7 @@ int iommu_setup(void) struct hvm_iommu *hd = domain_hvm_iommu(dom0); struct acpi_drhd_unit *drhd; struct iommu *iommu; - unsigned long i; + unsigned long i, status; if ( !vtd_enabled ) return 0; @@ -1804,6 +1797,10 @@ int iommu_setup(void) if ( enable_vtd_translation() ) goto error; + status = dmar_readl(iommu->reg, DMAR_PMEN_REG); + if (status & DMA_PMEN_PRS) + disable_pmr(iommu); + return 0; error: diff --git a/xen/arch/x86/hvm/vmx/vtd/utils.c b/xen/arch/x86/hvm/vmx/vtd/utils.c index fa907a544e..57964b2b6e 100644 --- a/xen/arch/x86/hvm/vmx/vtd/utils.c +++ b/xen/arch/x86/hvm/vmx/vtd/utils.c @@ -64,6 +64,26 @@ int vtd_hw_check(void) return 0; } +/* disable vt-d protected memory registers */ +void disable_pmr(struct iommu *iommu) +{ + unsigned long start_time, status; + + gdprintk(XENLOG_INFO VTDPREFIX, + "disabling protected memory registers\n"); + + dmar_writel(iommu->reg, DMAR_PMEN_REG, 0); + start_time = jiffies; + while (1) { + status = dmar_readl(iommu->reg, DMAR_PMEN_REG); + if ( (status & DMA_PMEN_PRS) == 0 ) + break; + if (time_after(jiffies, start_time + DMAR_OPERATION_TIMEOUT)) + panic("Cannot set QIE field for queue invalidation\n"); + cpu_relax(); + } +} + #if defined(__x86_64__) void print_iommu_regs(struct acpi_drhd_unit *drhd) { diff --git a/xen/include/asm-x86/hvm/vmx/intel-iommu.h b/xen/include/asm-x86/hvm/vmx/intel-iommu.h index b8bf433f6a..893cfaa70a 100644 --- a/xen/include/asm-x86/hvm/vmx/intel-iommu.h +++ b/xen/include/asm-x86/hvm/vmx/intel-iommu.h @@ -145,6 +145,10 @@ #define DMA_GSTS_QIES (((u64)1) <<26) #define DMA_GSTS_IRES (((u64)1) <<25) +/* PMEN_REG */ +#define DMA_PMEN_EPM (((u32)1) << 31) +#define DMA_PMEN_PRS (((u32)1) << 1) + /* CCMD_REG */ #define DMA_CCMD_INVL_GRANU_OFFSET 61 #define DMA_CCMD_ICC (((u64)1) << 63)